package utils;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.google.gson.Gson;
/** Class contains static methods for encrypting and decrypting serializable objects
*/
public class ObjCrypter {
/** The algorithm used for encryption */
private static String AES_ALG = "PBEWITHSHA256AND128BITAES-CBC-BC";
/** The password used by default if a pass is not provided in the arguments */
private static final char[] defaultPass = "s0Methin6!!".toCharArray();
private static byte[] salt = "a9v5n38s".getBytes();
/** Encrypts the Serializable object with AES
* @param plaintext the Serializable object to encrypt
* @param password the password to use for encryption, if it's null or empty the default pass will be used instead
* @return an encrypter String formatted as json containing the used cipher and the encrypted object
*/
public static String encryptAES(Serializable plaintext, String password) {
try{
final PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20);
final PBEKeySpec pbeKeySpec = new PBEKeySpec(
(password==null || password.equalsIgnoreCase(""))?defaultPass:password.toCharArray() );
final SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(AES_ALG);
final SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
final Cipher cipher = Cipher.getInstance(AES_ALG);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,pbeParamSpec);
return gson.toJson(new SealedObject(plaintext,cipher));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
/** Decrypts an AES encrypted String
* @param encString the String to decrypt, formatted as json containing the used cipher and the encrypted object
* @param password the password to use for decryption, if it's null or empty the default pass will be used instead
* @return a Serializable decrypted object
*/
public static Serializable decryptAES(String encString, String password) {
try{
final PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20);
final PBEKeySpec pbeKeySpec = new PBEKeySpec(
(password==null || password.equalsIgnoreCase(""))?defaultPass:password.toCharArray() );
final SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(AES_ALG);
final SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
final Cipher cipher = Cipher.getInstance(AES_ALG);
cipher.init(Cipher.DECRYPT_MODE,secretKey,pbeParamSpec);
return (Serializable) (gson.fromJson(encString, SealedObject.class)).getObject(cipher);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
/** A Gson object used for serialization and deserialization */
private static final Gson gson = new Gson();
/** Returns the hashed SHA-1 representation of the given text
* @param text the text to hash
* @return the SHA-1 representation of that text
*/
public static String toSHA1(String text) {
try {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes("UTF-8"));
final byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
System.out.println("No sha1 algorithm: " + e);
} catch (UnsupportedEncodingException e) {
System.out.println("Wrong encoding in string: " + e);
}
return text;
}
public static byte[] encrypt3DES(byte[] message, String password)
throws NoSuchAlgorithmException, UnsupportedEncodingException,
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException {
final byte[] digestOfPassword = MessageDigest.getInstance("md5")
.digest(password.getBytes("ISO-8859-1"));//"utf-8"
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[8]));
return cipher.doFinal(message);
}
public static byte[] decrypt3DES(byte[] message, String password)
throws NoSuchAlgorithmException, UnsupportedEncodingException,
InvalidKeyException, InvalidAlgorithmParameterException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
final byte[] digestOfPassword = MessageDigest.getInstance("md5")
.digest(password.getBytes("ISO-8859-1")); //"utf-8"
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[8]));
return decipher.doFinal(message);
}
}